package com.xinhe.web.service;

import com.xinhe.web.common.Result;
import com.xinhe.web.entity.AssetCount;
import com.xinhe.web.entity.AssetDetail;
import com.xinhe.web.enums.EnumConstantView;
import com.xinhe.web.reposity.AssetCountRepository;
import com.xinhe.web.reposity.AssetDetailRepository;
import com.xinhe.web.util.Snowflake;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
public class AssetCountService {
    private static final String ASSET_TYPE_NAME = "EAssetType";
    /*@Autowired
    private UserSessionManager userSessionManager;*/
    /*@Autowired
    private EnumConstantFactory enumConstantFactory;*/
    @Autowired
    private AssetCountRepository assetCountRepository;
    @Autowired
    private AssetCountService selfService;
    @Autowired
    private AssetDetailService assetDetailService;
    @Autowired
    private AssetDetailRepository assetDetailRepository;

    @Transactional
    public Result<AssetDetail> saveRemainderAsset(Long userId,String assetType,String tradeType,
                                                  BigDecimal tradeAmount,Long fBusinessId,
                                                  String remark,Date createTime) {
        //todo 和懿哥确认一下它们的值。
        BigDecimal tradeAmountMin = new BigDecimal(0);
        BigDecimal tradeAmountMax = new BigDecimal(0);
        BigDecimal remainderMin = new BigDecimal(0);
        BigDecimal remainderMax = new BigDecimal(0);
        if (null != tradeAmountMin && tradeAmount.abs().compareTo(tradeAmountMin) < 0) {
            return Result.failed(1001,assetType + "交易金额不能小于" + tradeAmountMin);
        }  if (null != tradeAmountMax && tradeAmount.abs().compareTo(tradeAmountMax) > 0) {
            return Result.failed(1002,assetType + "交易金额不能大于" + tradeAmountMax);
        }
        AssetCount assetCount = initAssetCount(assetType,userId);
        BigDecimal remainder = assetCount.getRemainder().add(tradeAmount).setScale(2, RoundingMode.HALF_UP);
        if(null != remainderMin && remainder.compareTo(remainderMin) < 0) {
            return Result.failed(1003,assetType + "余量不足，不能小于" + remainderMin);
        }if(null != remainderMax && remainder.compareTo(remainderMax) > 0) {
            return Result.failed(1004,assetType + "余量过多，不能大于" + remainderMax);
        }
        assetCount.setRemainder(remainder);
        assetCountRepository.saveAndFlush(assetCount);
        AssetDetail assetDetail = this.assetDetailService.saveAssetDetail(userId,assetType,tradeType,tradeAmount,fBusinessId,remark,createTime, remainder);
        return Result.ok(assetDetail);
    }
    @Transactional
    public AssetCount initAssetCount(String type, Long userId) {
        AssetCount assetCount = assetCountRepository.findOneByTypeAndUserId(type, userId);
        if (null == assetCount) {
            assetCount = new AssetCount();
            assetCount.setId(Snowflake.generateId());
            assetCount.setfUserId(userId);
            assetCount.setType(type);
            this.assetCountRepository.save(assetCount);
        }
        return assetCount;
    }

    public Result<AssetCount> findByTypeAndUserId(String type, Long userId) {
        Long queryUserId = userId;
        if (null == queryUserId) {
            return Result.failed(3001,"userId为空");
        }
        AssetCount assetCount = this.assetCountRepository.findOneByTypeAndUserId(type, queryUserId);
        return Result.ok(assetCount);
    }
    @Transactional
    public List<AssetCount> initAssetCount(Long userId) {
        List<AssetCount> assetCounts = new ArrayList<>();
        //EAssetType,本来从redis中查询的，这里写死
        List<EnumConstantView> assetTypes = getAssetTypeList();;
        for (EnumConstantView assetType : assetTypes) {
            AssetCount assetCount = this.assetCountRepository.findOneByTypeAndUserId(assetType.getName(), userId);
            if (null == assetCount) {
                assetCount = new AssetCount();
                assetCount.setfUserId(userId);
                assetCount.setType(assetType.getName());
                this.assetCountRepository.save(assetCount);
            }
            assetCounts.add(assetCount);
        }
        return assetCounts;
    }

    private List<EnumConstantView> getAssetTypeList() {
        List<EnumConstantView> assetTypes =new ArrayList<>();
        EnumConstantView enumConstantView1 = new EnumConstantView();
        enumConstantView1.setName("RMB");
        enumConstantView1.setLabel("人民币");
        enumConstantView1.setDetail("元");
        EnumConstantView enumConstantView2 = new EnumConstantView();
        enumConstantView2.setName("YUN_CHA_SEED");
        enumConstantView2.setLabel("云茶籽");
        enumConstantView2.setDetail("");
        EnumConstantView enumConstantView3 = new EnumConstantView();
        enumConstantView3.setName("NEW_YUN_CHA_SEED");
        enumConstantView3.setLabel("云茶籽");
        enumConstantView3.setDetail("");
        EnumConstantView enumConstantView4 = new EnumConstantView();
        enumConstantView4.setName("TEA_OIL_CARD");
        enumConstantView4.setLabel("茶油卡");
        enumConstantView4.setDetail("");
        EnumConstantView enumConstantView5 = new EnumConstantView();
        enumConstantView5.setName("CONSUMER_GOLD_RED_ENVELOPE");
        enumConstantView5.setLabel("消费金红包");
        enumConstantView5.setDetail("");
        EnumConstantView enumConstantView6 = new EnumConstantView();
        enumConstantView6.setName("UNFREEZING_CONSUMER_GOLD_RED_ENVELOPE");
        enumConstantView6.setLabel("解冻消费金红包");
        enumConstantView6.setDetail("");
        EnumConstantView enumConstantView7 = new EnumConstantView();
        enumConstantView7.setName("TEA_OIL");
        enumConstantView7.setLabel("茶油");
        enumConstantView7.setDetail("");
        assetTypes.add(enumConstantView1);
        assetTypes.add(enumConstantView2);
        assetTypes.add(enumConstantView3);
        assetTypes.add(enumConstantView4);
        assetTypes.add(enumConstantView5);
        assetTypes.add(enumConstantView6);
        assetTypes.add(enumConstantView7);
        return assetTypes;
    }
    public Result<Map<String, AssetCount>> findMapByUserId(Long userId) {
        Map<String, AssetCount> item = new HashMap<>();
        List<EnumConstantView> assetTypes = this.getAssetTypeList();
        for (EnumConstantView assetType : assetTypes) {
            if (null == item.get(assetType.getName())) {
                item.put(assetType.getName(), new AssetCount(userId, assetType.getName()));
            }
        }
        List<AssetCount> assetCounts = this.assetCountRepository.findByUserId(userId);
        for (AssetCount assetCount : assetCounts) {
            if (StringUtils.isNotBlank(assetCount.getType())) {
                item.put(assetCount.getType(), assetCount);
            }
        }
        return Result.ok(item);
    }

   /* @Transactional
    public BeanResult<AssetDetail> saveFrozenAsset(@Valid AssetTradeModel model) {
        BeanResult<AssetDetail> result = new BeanResult();
        IAssetType assetType = model.getAssetType();
        AssetCount assetCount = this.selfService.initAssetCount(assetType, model.getUserId());
        BigDecimal frozen = assetCount.getFrozen().add(model.getTradeAmount());
        if (null != assetType.getFrozenMin() && frozen
                .compareTo(assetType.getFrozenMin()) < 0) {
            result.addErrorView("冻结金额不能小于" + assetType.getFrozenMin());
            return result;
        }  if (null != assetType.getFrozenMax() && frozen
                .compareTo(assetType.getFrozenMax()) > 0) {
            result.addErrorView("冻结金额不能大于" + assetType.getFrozenMax());
            return result;
        }
        assetCount.setFrozen(frozen);
        this.assetCountDao.update((BaseEntityImpl)assetCount);
        AssetDetail assetDetail = this.assetDetailService.saveAssetDetail(model, frozen);
        result.setItem(assetDetail);
        return result;
    }


    @Transactional
    public BeanResult<AssetDetail> saveAvailableAsset(@Valid AssetTradeModel model) {
        BeanResult<AssetDetail> result = new BeanResult();
        IAssetType assetType = model.getAssetType();
        AssetCount assetCount = this.selfService.initAssetCount(assetType, model.getUserId());
        BigDecimal available = assetCount.getAvailable().add(model.getTradeAmount());
        if (null != assetType.getAvailableMin() && available
                .compareTo(assetType.getAvailableMin()) < 0) {
            result.addErrorView("待获得金额不能小于" + assetType.getAvailableMin());
            return result;
        }  if (null != assetType.getAvailableMax() && available
                .compareTo(assetType.getAvailableMax()) > 0) {
            result.addErrorView("待获得金额不能大于" + assetType.getAvailableMax());
            return result;
        }
        assetCount.setAvailable(available);
        this.assetCountDao.update((BaseEntityImpl)assetCount);
        AssetDetail assetDetail = this.assetDetailService.saveAssetDetail(model, available);
        result.setItem(assetDetail);
        return result;
    }

    public PageResult<AssetCountView> pageAssetCountByManager(AssetCountQuery query) {
        Integer total = Integer.valueOf(1);
        List<AssetCountView> views = null;
        if (0 < query.getLimit().intValue()) {
            total = this.assetCountDao.countAssetCount(query);
        }
        if (0 < total.intValue()) {
            views = this.assetCountDao.pageAssetCount(query);
        }
        if (0 > query.getLimit().intValue()) {
            if (null == views) {
                total = Integer.valueOf(0);
            } else {
                total = Integer.valueOf(views.size());
            }
        }
        return new PageResult(total, views);
    }


    public ListResult<AssetCount> findListBySelf() {
        Long userId = this.userSessionManager.getUserId();
        List<AssetCount> assetCounts = this.assetCountDao.findByUserId(userId);
        Map<String, AssetCount> item = new HashMap<>();
        List<EnumConstantFactory.EnumConstantView> assetTypes = this.enumConstantFactory.getEnumConfig("EAssetType");
        for (EnumConstantFactory.EnumConstantView assetType : assetTypes) {
            if (null == item.get(assetType.getName())) {
                item.put(assetType.getName(), new AssetCount(userId, assetType.getName()));
            }
        }

        for (AssetCount assetCount : assetCounts) {
            item.put(assetCount.getType(), assetCount);
        }

        List<AssetCount> items = new ArrayList<>();
        for (String key : item.keySet()) {
            items.add(item.get(key));
        }
        return new ListResult(items);
    }


    public BeanResult<Map<String, AssetCount>> findMapBySelf() {
        Long userId = this.userSessionManager.getUserId();
        List<EnumConstantFactory.EnumConstantView> assetTypes = this.enumConstantFactory.getEnumConfig("EAssetType");
        Map<String, AssetCount> item = new HashMap<>();
        for (EnumConstantFactory.EnumConstantView assetType : assetTypes) {
            item.put(assetType.getName(), new AssetCount(userId, assetType.getName()));
        }

        List<AssetCount> assetCounts = this.assetCountDao.findByUserId(userId);
        for (AssetCount assetCount : assetCounts) {
            if (StringUtils.isNotBlank(assetCount.getType())) {
                item.put(assetCount.getType(), assetCount);
            }
        }

        return new BeanResult(item);
    }


    protected IBaseDao<AssetCount> getRealDao() {
        return (IBaseDao<AssetCount>)this.assetCountDao;
    }


    @Deprecated
    @Transactional
    public AssetDetail saveaAsetCount(Long userId, String assetType, String tradeType, BigDecimal money, Long businessId, String remark) {
        AssetCount assetCount = this.assetCountDao.findOneByTypeAndUserId(assetType, userId);
        if (null == assetCount) {
            assetCount = new AssetCount();
            assetCount.setUserId(userId);
            assetCount.setType(assetType);
            this.assetCountDao.save((BaseEntityImpl)assetCount);
        }
        BigDecimal remainder = assetCount.getRemainder().subtract(money);
        if (remainder.floatValue() < 0.0F) {
            throw new BusinessException("余额不足");
        }
        assetCount.setRemainder(remainder);

        this.assetCountDao.update((BaseEntityImpl)assetCount);

        AssetDetail assetDetail = new AssetDetail();
        assetDetail.setBusinessId(businessId);
        assetDetail.setRemainder(remainder);
        assetDetail.setRemark(remark);
        assetDetail.setAssetType(assetType);
        assetDetail.setTradeAmount(money.multiply(new BigDecimal(-1)));
        assetDetail.setTradeType(tradeType);
        assetDetail.setUserId(userId);
        if (StringUtils.isBlank(remark)) {
            assetDetail.setRemark(assetType);
        } else {
            assetDetail.setRemark(remark);
        }
        this.assetDetailDao.save((BaseEntityImpl)assetDetail);

        return assetDetail;
    }
    */
}
